package teatime.core.dao.support;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import net.sf.ezmorph.bean.MorphDynaBean;
import net.sf.json.JSONObject;

public class Filters {

	private List<Filter> filterList = 
		new ArrayList<Filter>();			// 过滤条件容器
	
	/**
	 * 构造方法，根据过滤条件字符串生成Filters类.
	 */
	@SuppressWarnings("unchecked")
	public Filters(String sFilters) throws ParseException {
		// 将接收到的JSON对象转换成MorphDynaBean对象
		MorphDynaBean _Filters = (MorphDynaBean)JSONObject.toBean(
				JSONObject.fromObject(sFilters));
		// 解析Filter，可能存在多个Filter，所以要放入容器中
		List<MorphDynaBean> _filterList = (List)_Filters.get("filter");
		for (Iterator<MorphDynaBean> it = _filterList.iterator(); it.hasNext();) {
			// Filter的内容由field,data(type, value, comparison)组成
			Filter filter = new Filters.Filter();
			
			MorphDynaBean _filter = (MorphDynaBean) it.next();
			
			filter.setField((String)_filter.get("field"));
			filter.addData((MorphDynaBean)_filter.get("data"));
			
			filterList.add(filter);
		}
	}

	/**
	 * 生成过滤条件
	 */
	public Criterion getCiterion() {
		
		Conjunction criterion = Restrictions.conjunction();
		
		for (Iterator<Filter> it = filterList.iterator(); it.hasNext();) {
			((Filter) it.next()).addCriterion(criterion);
		}
		return criterion;
	}
	
	private class Filter {
		private String field;								// 字段
		private List<Data> datas = new ArrayList<Data>();	// 过滤条件的内容
		// 添加过滤条件的内容
		public void addData(MorphDynaBean _data) throws ParseException {
			Data data = new Data(_data);
			datas.add(data);
		}
		
		/**
		 * 生成过滤条件
		 */
		public void addCriterion(Conjunction criterion) {
			for (Iterator<Data> it = getDatas().iterator(); it.hasNext();) {
				Data data = (Data)it.next();
				data.addCriterion(criterion, getField());
			}
		}
		
		public List<Data> getDatas() {
			return datas;
		}
		public String getField() {
			return field;
		}
		public void setField(String field) {
			this.field = field;
		}
	}
	
	private class Data {
		private String type;			// 字段类型
		private Object value;			// 过滤值
		private String comparison;		// 比较符
		
		public Data(String type, Object value, String comparison) throws ParseException {
			this.type = type;
			this.comparison = comparison;
			// 当类型为日期型时，需要将接收到的字符型转为日期型
			if (type.equals("date")) {
				SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
				this.value = sdf.parse((String)value);
			} else if (type.equals("numeric")) {
				// 将数据类型都转成BigDecimal(注意：对应的hbm.xml也都要写成big_decimal)
				this.value = BigDecimal.valueOf(Double.valueOf(value.toString()));
			} else {
				this.value = value;
			}
		}
		
		public Data(MorphDynaBean _data) throws ParseException {
			this((String)_data.get("type"), 
					_data.get("value"), 
					(String)_data.get("comparison"));
		}
		
		/**
		 * 生成过滤条件
		 */
		public void addCriterion(Conjunction criterion, String field) {
			// 根据比较符设定like、大于、小于和等于
			if (getComparison().equals("")) {
				criterion.add(Restrictions.like(field, getValue()));
			} else if (comparison.equals("gt")) {
				criterion.add(Restrictions.gt(field, getValue()));
			} else if (comparison.equals("lt")) {
				criterion.add(Restrictions.lt(field, getValue()));
			} else if (comparison.equals("eq")) {
				criterion.add(Restrictions.eq(field, getValue()));
			}
		}
		
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Object getValue() {
			return value;
		}
		public void setValue(Object value) {
			this.value = value;
		}
		public String getComparison() {
			return comparison;
		}
		public void setComparison(String comparison) {
			this.comparison = comparison;
		}
	}
}
